package com.yiyuzi.admin.common;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yiyuzi.admin.privilege.domain.entity.PrivilegeEntity;
import com.yiyuzi.admin.privilege.service.PrivilegeService;
import com.yiyuzi.admin.role.domain.entity.RolePrivilegeEntity;
import com.yiyuzi.admin.role.service.RolePrivilegeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 每次系统开始运行时，读取rest接口路径保存到权限表，并删除多余的路径和对应联系
 *
 * @author yiyuzi
 * @date 2021/5/8 13:26
 */

@Slf4j
@Component
public class GetUrlLoader implements ApplicationContextAware {
    @Autowired
    private PrivilegeService privilegeService;

    @Autowired
    private RolePrivilegeService rolePrivilegeService;

    private Long father_id = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, Object> beans = applicationContext.getBeansWithAnnotation(RestController.class);
        List<Long> idList = new ArrayList<>();
        for (String beanName : beans.keySet()) {
            Object value = applicationContext.getBean(beanName);
            if (value == null) {
                continue;
            }
            RequestMapping requestMapping = AnnotationUtils.findAnnotation(value.getClass(), RequestMapping.class);
            if (requestMapping == null) {
                continue;
            }
            String path = requestMapping.value()[0];
            Api api = AnnotationUtils.findAnnotation(value.getClass(), Api.class);
            String desc = api.tags()[0];
            log.info("path: {} , desc : {}" , path, desc);
            Method[] methods = value.getClass().getMethods();

            father_id = null;
            setPrivilege(path,desc);
            father_id = privilegeService.findByPath(path).getId();
            idList.add(father_id);

            for (Method method : methods) {
                //每个方法必定含有下面的注解中的其中一个
                ApiOperation apiOperation = AnnotationUtils.findAnnotation(method, ApiOperation.class);
                String url = "";
                desc = "";
                if (apiOperation != null) {
                    desc = apiOperation.value();
                }
                RequestMapping mapping = AnnotationUtils.findAnnotation(method, RequestMapping.class);
                PostMapping postMapping = AnnotationUtils.findAnnotation(method, PostMapping.class);
                GetMapping getMapping = AnnotationUtils.findAnnotation(method, GetMapping.class);
                PutMapping putMapping = AnnotationUtils.findAnnotation(method, PutMapping.class);
                DeleteMapping deleteMapping = AnnotationUtils.findAnnotation(method, DeleteMapping.class);
                if (postMapping != null) {
                    url = path + postMapping.value()[0];
                } else if (getMapping != null) {
                    url = path + getMapping.value()[0];
                } else if (putMapping != null) {
                    url = path + putMapping.value()[0];
                } else if (deleteMapping != null) {
                    url = path + deleteMapping.value()[0];
                } else if (mapping != null) {  //mapping 顺序一定要在后面
                    url = path + mapping.value()[0];
                } else {
                    continue;
                }
                log.info("url : {}  , desc : {}", url, desc);

                //url信息入库
                idList.add(setPrivilege(url, desc));
            }
        }
        // 删除相关的联系表数据
        this.deleteRelation(idList);
        // 删除多余的路径
        privilegeService.removeNotInIds(idList);
    }

    private Long setPrivilege(String path, String desc){
        PrivilegeEntity entity = privilegeService.findByPath(path);
        if (entity == null){
            entity = new PrivilegeEntity();
            entity.setPath(path);
            entity.setPrivilegeName(desc);
            entity.setFatherId(father_id);
            privilegeService.save(entity);
            return privilegeService.findByPath(path).getId();
        }else {
            entity.setPath(path);
            entity.setPrivilegeName(desc);
            entity.setFatherId(father_id);
            privilegeService.updateById(entity);
            return entity.getId();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    void deleteRelation(List<Long> list){
        List<PrivilegeEntity> entityList = privilegeService.list();
        for(PrivilegeEntity privilegeEntity : entityList){
            if (!list.contains(privilegeEntity.getId())){
                Long id = privilegeEntity.getId();
                List<RolePrivilegeEntity> rolePrivilegeDTOList = rolePrivilegeService.list(new QueryWrapper<RolePrivilegeEntity>()
                        .eq(id != null,"privilege_id", id));
                for(RolePrivilegeEntity entity : rolePrivilegeDTOList){
                    rolePrivilegeService.removeById(entity.getId());
                }
            }
        }
    }

}
